﻿// <copyright file="UpdateViewModelTests.cs" company="Mooville">
//   Copyright © 2010 Roger Deetz. All rights reserved.
// </copyright>

namespace Mooville.QUno.ViewModel.Tests
{
    using System;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Mooville.Common.Testing.Mocks;
    using Mooville.Common.Updates;
    using Mooville.QUno.Properties;
    using Mooville.QUno.ViewModel;

    [TestClass]
    public class UpdateViewModelTests
    {
        [TestMethod]
        public void Constructor_ShouldNotThrow()
        {
            UpdateViewModel target = new UpdateViewModel();
            Assert.IsNotNull(target);

            return;
        }

        [TestMethod]
        public void AfterConstructor_Title_ShouldBeNull()
        {
            UpdateViewModel target = new UpdateViewModel();
            Assert.IsNull(target.Title);

            return;
        }

        [TestMethod]
        public void AfterConstructor_Message_ShouldBeNull()
        {
            UpdateViewModel target = new UpdateViewModel();
            Assert.IsNull(target.Message);

            return;
        }

        [TestMethod]
        public void AfterConstructor_IsWorking_ShouldBeFalse()
        {
            UpdateViewModel target = new UpdateViewModel();
            Assert.IsFalse(target.IsWorking);

            return;
        }

        [TestMethod]
        public void AfterConstructor_HasUpdate_ShouldBeFalse()
        {
            UpdateViewModel target = new UpdateViewModel();
            Assert.IsFalse(target.HasUpdate);

            return;
        }

        [TestMethod]
        public void AfterConstructor_UpdateAddress_ShouldBeNull()
        {
            UpdateViewModel target = new UpdateViewModel();
            Assert.IsNull(target.UpdateAddress);

            return;
        }

        [TestMethod]
        public void CancelCheckForUpdates_ShouldNotThrow()
        {
            UpdateViewModel target = new UpdateViewModel(new TestUpdateService());
            target.CancelCheckForUpdates();

            return;
        }

        [TestMethod]
        public void AfterCheckForUpdates_Error_ShouldBeCorrect()
        {
            // This technique of hooking up an event handler in the test method 
            // and then asserting in the handler doesn't really work right.
            // If one of the assertion fails, the test run does indeed report 
            // the error (and you can figure out what failed from the stack trace)
            // but the test results don't map the failure back to the right test method.
            // I don't know if this is a recurring issue when unit testing 
            // view models, or if this just applies to view model that use background threads.
            UpdateViewModel target = new UpdateViewModel(new TestUpdateService(UpdateResultType.Error));
            target.CheckForUpdatesCompleted += new EventHandler(this.CheckForUpdatesCompleted_Error);
            target.CheckForUpdates();

            return;
        }

        [TestMethod]
        public void AfterCheckForUpdates_NoUpdateAvailable_ShouldBeCorrect()
        {
            UpdateViewModel target = new UpdateViewModel(new TestUpdateService(UpdateResultType.NoUpdateAvailable));
            target.CheckForUpdatesCompleted += new EventHandler(this.CheckForUpdatesCompleted_NoUpdateAvailable);
            target.CheckForUpdates();

            return;
        }

        [TestMethod]
        public void AfterCheckForUpdates_UpdateAvailable_ShouldBeCorrect()
        {
            UpdateViewModel target = new UpdateViewModel(new TestUpdateService(UpdateResultType.UpdateAvailable));
            target.CheckForUpdatesCompleted += new EventHandler(this.CheckForUpdatesCompleted_UpdateAvailable);
            target.CheckForUpdates();

            return;
        }

        private void CheckForUpdatesCompleted_Error(object sender, EventArgs e)
        {
            UpdateViewModel target = sender as UpdateViewModel;
            Assert.IsFalse(target.IsWorking);
            Assert.AreEqual(Resources.TitleCheckForUpdatesError, target.Title);
            Assert.AreEqual(TestUpdateService.DefaultTestExceptionMessage, target.Message);
            Assert.IsFalse(target.HasUpdate);
            Assert.IsNull(target.UpdateAddress);

            return;
        }

        private void CheckForUpdatesCompleted_NoUpdateAvailable(object sender, EventArgs e)
        {
            UpdateViewModel target = sender as UpdateViewModel;
            Assert.IsFalse(target.IsWorking);
            Assert.AreEqual(Resources.TitleCheckForUpdatesNoUpdateAvailable, target.Title);
            Assert.AreEqual(String.Empty, target.Message);
            Assert.IsFalse(target.HasUpdate);
            Assert.IsNull(target.UpdateAddress);

            return;
        }

        private void CheckForUpdatesCompleted_UpdateAvailable(object sender, EventArgs e)
        {
            UpdateViewModel target = sender as UpdateViewModel;
            Assert.IsFalse(target.IsWorking);
            Assert.AreEqual(Resources.TitleCheckForUpdatesUpdateAvailable, target.Title);
            Assert.AreEqual(Resources.MessageCheckForUpdatesUpdateAvailable, target.Message);
            Assert.IsTrue(target.HasUpdate);
            Assert.IsFalse(String.IsNullOrEmpty(target.UpdateAddress));

            return;
        }
    }
}
